home *** CD-ROM | disk | FTP | other *** search
Oberon Text | 1995-08-22 | 10.6 KB | 289 lines | [TEXT/.Ob4] |
- Syntax10.Scn.Fnt
- FoldElems
- Syntax10.Scn.Fnt
- (* ----------------------------------------------------------
- Backup does an incremental backup between two directories, i.e. only the files that
- have changed since the last backup are copied.
- Backup.WriteFiles ( {source destination} ~ | "^")
- Source and destination are given as Macintosh path names starting with the volume name
- and ending with ":". If a path name contains blanks it must be written under quotes.
- Example:
- Backup.WriteFiles Othello:Text:Lectures:EiP: hm:Backup:EiP: ~
- ----------------------------------------------------------*)
- Syntax10i.Scn.Fnt
- StampElems
- Alloc
- 8 May 95
- Syntax10.Scn.Fnt
- VAR i: INTEGER;
- BEGIN
- i := 0; WHILE in[i] # 0X DO out[i+1] := in[i]; INC(i) END;
- out[0] := CHR(i)
- END MakeStr255;
- Syntax10.Scn.Fnt
- VAR res: INTEGER;
- BEGIN
- NEW(par);
- par.ioCompletion := 0; par.ioNamePtr := SYSTEM.ADR(spec.name);
- par.ioVRefNum := spec.vRefNum; par.ioDirID := spec.parID; par.ioFDirIndex := 0;
- res := PBGetCatInfo(par); ASSERT(res = 0)
- END GetFileInfo;
- Syntax10.Scn.Fnt
- VAR res: INTEGER;
- BEGIN
- NEW(par);
- par.ioCompletion := 0; par.ioNamePtr := SYSTEM.ADR(spec.name);
- par.ioVRefNum := spec.vRefNum; par.ioDrDirID := spec.parID; par.ioFDirIndex := 0;
- res := PBGetCatInfo(par); ASSERT(res = 0)
- END GetDirInfo;
- Syntax10.Scn.Fnt
- VAR ch, start: CHAR; i: INTEGER;
- BEGIN
- REPEAT In.Char(ch) UNTIL (ch > " ") OR ~In.Done;
- i := 1;
- IF (ch = '"') OR (ch = "'") THEN
- start := ch; In.Char(ch);
- WHILE In.Done & (ch # start) DO s[i] := ch; INC(i); In.Char(ch) END;
- In.Char(ch);
- ELSE
- WHILE In.Done & (ch > " ") DO s[i] := ch; INC(i); In.Char(ch) END
- END;
- s[i] := 0X; s[0] := CHR(i-1)
- END ReadString;
- Syntax10.Scn.Fnt
- VAR i: INTEGER;
- BEGIN
- FOR i := 1 TO ORD(s[0]) DO Out.Char(s[i]) END
- END PrintString;
- Syntax10.Scn.Fnt
- VAR i: INTEGER;
- BEGIN
- IF a[0] # b[0] THEN RETURN FALSE END;
- i := ORD(a[0]); WHILE (i > 0) & (a[i] = b[i]) DO DEC(i) END;
- RETURN i = 0
- END EqualString;
- Syntax10.Scn.Fnt
- VAR f: File;
- BEGIN
- NEW(f); f.next := NIL; f.spec := spec;
- f.date := info.ioFlMdDat; f.len := info.ioFlLgLen; f.rlen := info.ioFlRLgLen;
- f.creator := info.ioFlFndrInfo.fdCreator; f.type := info.ioFlFndrInfo.fdType;
- IF f.len > maxLen THEN maxLen := f.len END;
- IF f.rlen > maxLen THEN maxLen := f.rlen END;
- RETURN f
- END NewFile;
- Syntax10.Scn.Fnt
- VAR g: File;
- BEGIN
- g := d.files;
- WHILE (g # NIL) & ~EqualString(f.spec.name, g.spec.name) DO g := g.next END;
- RETURN g
- END ThisFile;
- Syntax10.Scn.Fnt
- FoldElems
- Syntax10.Scn.Fnt
- IF g # NIL THEN
- res := Sys.FSpDelete(g.spec); ASSERT(res = 0, 99)
- ELSE
- NEW(g);
- FOR i := 0 TO ORD(f.spec.name[0]) DO s[i] := f.spec.name[i] END;
- res := Sys.FSMakeFSSpec(dt.spec.vRefNum, dt.dirID, s, g.spec); ASSERT(res = fnfErr, 98)
- END;
- res := Sys.FSpCreate(g.spec, f.creator, f.type, Sys.smSystemScript); ASSERT(res = 0, 97);
- Syntax10i.Scn.Fnt
- Syntax10.Scn.Fnt
- res := Sys.FSpOpenDF(f.spec, 0, fRef); ASSERT(res = 0, 96);
- res := Sys.FSpOpenDF(g.spec, 0, gRef); ASSERT(res = 0, 95);
- res := Sys.FSRead(fRef, f.len, SYSTEM.ADR(buf^)); ASSERT(res = 0, 94);
- res := Sys.FSWrite(gRef, f.len, SYSTEM.ADR(buf^)); ASSERT(res = 0, 93);
- res := Sys.FSClose(fRef); ASSERT(res = 0, 92);
- res := Sys.FSClose(gRef); ASSERT(res = 0, 91);
- PrintString(f.spec.name);
- Syntax10.Scn.Fnt
- IF f.rlen > 0 THEN
- res := Sys.FSpOpenRF(f.spec, 0, fRef); ASSERT(res = 0, 90);
- res := Sys.FSpOpenRF(g.spec, 0, gRef); ASSERT(res = 0, 89);
- res := Sys.FSRead(fRef, f.rlen, SYSTEM.ADR(buf^)); ASSERT(res = 0, 88);
- res := Sys.FSWrite(gRef, f.rlen, SYSTEM.ADR(buf^)); ASSERT((res = 0) OR (res = -5000), 87);
- IF res = -5000 THEN
- Out.String(" (error -5000)")
- END;
- res := Sys.FSClose(fRef); ASSERT(res = 0, 86);
- res := Sys.FSClose(gRef); ASSERT(res = 0, 85);
- Out.String(" + resources")
- END;
- VAR res, i: INTEGER; s: Sys.Str255; fRef, gRef: INTEGER; info: FileInfo;
- BEGIN
- create empty g on dt
- copy data fork
- copy resource fork
- Out.String(" saved$"); INC(savedFiles)
- END SaveFile;
- Syntax10.Scn.Fnt
- VAR d: Directory; info: DirInfo; res: INTEGER;
- BEGIN
- NEW(d); d.next := NIL; d.files := NIL; d.dirs := NIL;
- d.spec := spec;
- GetDirInfo(spec, info); d.dirID := info.ioDrDirID; d.date := info.ioDrMdDat;
- RETURN d
- END NewDir;
- Syntax10.Scn.Fnt
- VAR spec: Sys.FSSpec; s: Sys.Str255; res, i: INTEGER; dummy: LONGINT;
- BEGIN
- FOR i := 0 TO ORD(df.spec.name[0]) DO s[i] := df.spec.name[i] END;
- res := Sys.FSMakeFSSpec(parent.spec.vRefNum, parent.dirID, s, spec); ASSERT(res = fnfErr, 29);
- res := Sys.FSpDirCreate(spec, Sys.smSystemScript, dummy); ASSERT(res = 0, 30);
- dt := NewDir(spec)
- END CreateDir;
- Syntax10.Scn.Fnt
- VAR g: File;
- BEGIN
- g := d.dirs;
- WHILE (g # NIL) & ~EqualString(f.spec.name, g.spec.name) DO g := g.next END;
- RETURN g
- END ThisDir;
- Syntax10.Scn.Fnt
- VAR f: File; i: INTEGER;
- BEGIN
- FOR i := 1 TO indent DO Out.String(" ") END;
- Out.String("--- "); PrintString(d.spec.name); Out.Ln;
- f := d.files;
- WHILE f # NIL DO
- FOR i := 1 TO indent DO Out.String(" ") END;
- Out.String(" "); PrintString(f.spec.name); Out.Ln;
- f := f.next
- END;
- f := d.dirs;
- WHILE f # NIL DO PrintDir(f(Directory), indent + 1); f := f.next END
- END PrintDir;
- Syntax10.Scn.Fnt
- VAR f: File; d1: Directory; par: FileInfo; res, n, i: INTEGER; spec: Sys.FSSpec; s: Sys.Str255;
- BEGIN
- n := 1; Out.Char(".");
- NEW(par); par.ioCompletion := 0; par.ioVRefNum := d.spec.vRefNum;
- LOOP
- s[0] := 0X; par.ioNamePtr := SYSTEM.ADR(s);
- par.ioDirID := d.dirID;
- par.ioFDirIndex := n; INC(n);
- res := Sys.PBGetCatInfo(par);
- IF res = 0 THEN
- res := Sys.FSMakeFSSpec(d.spec.vRefNum, d.dirID, s, spec); ASSERT(res = 0);
- IF ODD(par.ioFlAttrib DIV 16) THEN (*directory*)
- d1 := NewDir(spec); d1.next := d.dirs; d.dirs := d1
- ELSE (*file*)
- f := NewFile(spec, par); f.next := d.files; d.files := f
- END
- ELSIF res = fnfErr THEN EXIT
- ELSE HALT(20)
- END
- END;
- f := d.dirs;
- WHILE f # NIL DO FillDir(f(Directory)); f := f.next END
- END FillDir;
- Syntax10.Scn.Fnt
- VAR f, g: File; first: BOOLEAN;
- BEGIN
- f := df.files; first := TRUE;
- WHILE f # NIL DO
- g := ThisFile(dt, f);
- IF (g = NIL) OR (f.date > g.date) THEN
- IF first THEN Out.String("-- "); PrintString(df.spec.name); Out.Ln; first := FALSE END;
- SaveFile(f, g, dt)
- END;
- f := f.next
- END;
- f := df.dirs;
- WHILE f # NIL DO
- g := ThisDir(dt, f);
- IF g = NIL THEN CreateDir(f(Directory), dt, g) END;
- SaveDir(f(Directory), g(Directory));
- f := f.next
- END SaveDir;
- Syntax10b.Scn.Fnt
- Syntax10.Scn.Fnt
- VAR path: Sys.Str255; df, dt: Directory; res: INTEGER; spec: Sys.FSSpec;
- BEGIN
- In.Open; Out.Open; savedFiles := 0;
- LOOP
- ReadString(path);
- IF (path[0] = 0X) OR (path[1] = "~") THEN EXIT END;
- res := Sys.FSMakeFSSpec(0, 0, path, spec);
- IF res # 0 THEN Out.F("-- Invalid source directory. res = #$", res); EXIT END;
- df := NewDir(spec);
- ReadString(path);
- res := Sys.FSMakeFSSpec(0, 0, path, spec);
- IF res # 0 THEN Out.F("-- Invalid destination directory. res = #$", res); EXIT END;
- dt := NewDir(spec);
- maxLen := 0;
- Out.String("Reading directories");
- FillDir(df); FillDir(dt);
- Out.Ln;
- NEW(buf, maxLen);
- (*PrintDir(df, 0); PrintDir(dt, 0);*)
- SaveDir(df, dt)
- END;
- Out.F("$# files saved$", savedFiles);
- Out.Close; buf := NIL
- END WriteFiles;
- Documentation
- MODULE Backup; (* HM
- IMPORT Sys, In, Out, SYSTEM;
- CONST
- fnfErr = -43;
- File = POINTER TO FileDesc;
- FileDesc = RECORD
- next: File;
- spec: Sys.FSSpec;
- date, len, rlen, creator, type: LONGINT
- END;
- Directory = POINTER TO DirectoryDesc;
- DirectoryDesc = RECORD (FileDesc)
- dirID: LONGINT;
- files: File; (*the files in this directory*)
- dirs: File (*the subdirectories in this directory*)
- END;
- DirInfo = POINTER TO DirInfoDesc;
- DirInfoDesc = RECORD (Sys.CInfoPBRec)
- ioDrUsrWds: Sys.DInfo;
- ioDrDirID: LONGINT;
- ioDrNmFls: INTEGER;
- f3: ARRAY 9 OF INTEGER;
- ioDrCrDat: LONGINT;
- ioDrMdDat: LONGINT;
- ioDrBkDat: LONGINT;
- ioDrFndrInfo: Sys.DXInfo;
- ioDrParID: LONGINT
- END;
- FileInfo = Sys.CInfoPBFilePtr;
- maxLen: LONGINT; (*max. file length (determines buffer sizes)*)
- buf: POINTER TO ARRAY OF CHAR; (*files are copied via this buffer*)
- savedFiles: LONGINT; (*number of saved files*)
- PBGetCatInfo: PROCEDURE (parm: Sys.ParmBlkPtr): INTEGER;
- (*--- toolbox*)
- PROCEDURE MakeStr255 (VAR in: ARRAY OF CHAR; VAR out: Sys.Str255);
- PROCEDURE GetFileInfo (spec: Sys.FSSpec; VAR par: FileInfo);
- PROCEDURE GetDirInfo (spec: Sys.FSSpec; VAR par: DirInfo);
- (*--- auxiliaries*)
- PROCEDURE ReadString (VAR s: ARRAY OF CHAR);
- PROCEDURE PrintString (s: ARRAY OF CHAR);
- PROCEDURE EqualString (a, b: ARRAY OF CHAR): BOOLEAN;
- (*--- files*)
- PROCEDURE NewFile (spec: Sys.FSSpec; info: FileInfo): File;
- PROCEDURE ThisFile (d: Directory; f: File): File;
- PROCEDURE SaveFile (f, g: File; dt: Directory);
- (*--- directories*)
- PROCEDURE NewDir (spec: Sys.FSSpec): Directory;
- PROCEDURE CreateDir (df, parent: Directory; VAR dt: File);
- PROCEDURE ThisDir (d: Directory; f: File): File;
- PROCEDURE PrintDir (d: Directory; indent: INTEGER);
- PROCEDURE FillDir (d: Directory);
- PROCEDURE SaveDir (df, dt: Directory);
- PROCEDURE WriteFiles*;
- BEGIN
- Sys.Assign("PBGetCatInfoSync", SYSTEM.ADR(PBGetCatInfo));
- END Backup.
- Backup.WriteFiles Othello:Text:Vorlesungen:PI2: hm:Backup:PI2: ~
- Backup.WriteFiles "Othello:Text:Vorlesungen:EiP:" hm:Backup:EiP: ~
- Backup.WriteFiles Othello:AA: hm:Backup: ~
- System.Free Backup~
-